package com.sfpay.coreplatform.order.service.composite.impl;

import java.sql.SQLException;
import java.util.List;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.sfpay.coreplatform.order.common.OrderResponseCode;
import com.sfpay.coreplatform.order.common.enums.tradeStatus;
import com.sfpay.coreplatform.order.service.composite.QueryOrderService;
import com.sfpay.coreplatform.order.service.composite.common.PayContext;
import com.sfpay.coreplatform.order.service.exception.OrderServiceException;
import com.sfpay.coreplatform.order.service.validate.ValidateNULL;
import com.sfpay.coreplatform.order.valueobject.dto.PayRequest;
import com.sfpay.coreplatform.order.valueobject.dto.Response;
import com.sfpay.coreplatform.order.valueobject.tmo.TradeOrder;
import com.sfpay.coreplatform.order.common.enums.TradeType;

@Service
public class TradeHandler extends AbstractHandler {

	// oracel 唯一 返回码
	private static final int DB_ORACLE_UNIQUENESS = 1;

	private final static Logger logger = LoggerFactory
			.getLogger(TradeHandler.class);
	@Resource
	private QueryOrderService queryOrderService;

	@Override
	public Response Handler(PayRequest request, PayContext payContext)
			throws OrderServiceException {

		Response response = new Response();
		String tradeOrderNo = "";

		TradeOrder tradeOrder = new TradeOrder();
		tradeOrderNo = this.getTradeOrderDao().getNextOrderNo();
		tradeOrder.setOrderNo(tradeOrderNo);
		tradeOrder.setDetailInfo(request.getTradeInfo());
		tradeOrder.setSubject(request.getSubject());
		tradeOrder.setMemberNo(request.getPlatformMemberNo());
		tradeOrder.setBusinessType(request.getBusinessType());
		tradeOrder.setOrderAmt(request.getPayAmt());
		tradeOrder.setOrderStatus(tradeStatus.PROCESSING);
		tradeOrder.setMerchantOrderNo(request.getOutTradeNo());
		tradeOrder.setBusinessSn(request.getOutTradeNo());
		tradeOrder.setOrderType(request.getOrderType());
		tradeOrder.setTradeType(payContext.getTradeType());

		try {
			// 在前面并能检查唯一键是不是重复
			this.getTradeOrderDao().addTradeOrderEx(tradeOrder);// 交易订单扩展
			
			this.getTradeOrderDao().addTradeOrder(tradeOrder);// 交易订单
		} catch (Exception e) {
			if (SQLException.class.isInstance(e.getCause())) {
				int errCode = ((SQLException) e.getCause()).getErrorCode();
				if (errCode == DB_ORACLE_UNIQUENESS) {// 唯一性约束

					tradeOrderNo=uniqueHandler(request,payContext);
					if(ValidateNULL.checkStringNull(tradeOrderNo)){//交易订单号为空
						logger.error("outTradeNo:" + request.getOutTradeNo()
								+ " save exception ", e);
						throw new OrderServiceException(
								OrderResponseCode.ORDER_DB_EXCEPTION,
								" oracle errcode:" + errCode + " outTradeNo:"
										+ request.getOutTradeNo()
										+ " save exception ", e);
					}
				} else {
					logger.error("outTradeNo:" + request.getOutTradeNo()
							+ " save exception ", e);
					throw new OrderServiceException(
							OrderResponseCode.ORDER_DB_EXCEPTION,
							" oracle errcode:" + errCode + " outTradeNo:"
									+ request.getOutTradeNo()
									+ " save exception ", e);
				}

			} else {
				logger.error("outTradeNo:" + request.getOutTradeNo()
						+ " save exception ", e);
				throw new OrderServiceException(
						OrderResponseCode.ORDER_DB_EXCEPTION, " outTradeNo:"
								+ request.getOutTradeNo() + " save exception ",
						e);
			}
		}

		payContext.setTradeNo(tradeOrderNo);
		response.setReturnCode(OrderResponseCode.ORDER_RESPONSE_SUCESS);

		return response;
	}

	/**
	 * 已经存订单处理
	 * @param request
	 * @param payContext	 * 
	 * @return	 * 
	 */
	private String uniqueHandler(PayRequest request, PayContext payContext) throws OrderServiceException  {
		String tradeOrderNo = "";
		List<TradeOrder> tradeOrders = queryOrderService
				.queryPayTradeByOutTradeNo(request.getPlatformMemberNo(),
						request.getOutTradeNo());

		if (tradeOrders == null || tradeOrders.size() == 0) {
			 return tradeOrderNo;
		}
		
		for (TradeOrder trade : tradeOrders) {

			if (payContext.getTradeType().equals(trade.getTradeType())) {// 交易类型是否相同
				if (tradeStatus.FAILURE.equals(trade.getOrderStatus())) {
					
					if(TradeType.PAY==trade.getTradeType()){//支付
						tradeOrderNo = trade.getOrderNo();
						break;
					}else if(TradeType.CANCEL==trade.getTradeType()){//为撤消
						
						tradeStatus status = getTradeStatus(tradeOrders,
								TradeType.REVERSE);
						if (status == null || status == tradeStatus.FAILURE) {//是否存在已经冲正
							
							tradeOrderNo = trade.getOrderNo();
							break;
						}
						
						
					}else if(TradeType.REVERSE==trade.getTradeType()){//为撤消
						
						tradeStatus status = getTradeStatus(tradeOrders,
								TradeType.CANCEL);
						if (status == null || status == tradeStatus.FAILURE) {//是否存在已经撤消
							
							tradeOrderNo = trade.getOrderNo();
							break;
						}
					}
					
				} else  if (tradeStatus.SUCCESS.equals(trade.getOrderStatus())) {
					
					throw new OrderServiceException(
							OrderResponseCode.ORDER_ALREADY_SUCESS,
							 " outTradeNo:"
									+ request.getOutTradeNo()
									+ " already sucess ", null);
					
				}else if (tradeStatus.PROCESSING.equals(trade.getOrderStatus())) {
					
					throw new OrderServiceException(
							OrderResponseCode.ORDER_RESPONSE,
							 " outTradeNo:"
									+ request.getOutTradeNo()
									+ " processing not handler ", null);
				}
			}
		}

		return tradeOrderNo;
	}

	@Override
	public String getHandlerName() {
		 
		return "PayStatusHandler";
	}
	
	 

}
